﻿using Sessionizer.Core;
using Sessionizer.Samples.Model;

namespace Sessionizer.Samples.Sessionized.TopBuilder
{
    /// <summary>
    ///     Implementation is based on session.
    ///     Code is just a wrapper over session.
    /// </summary>
    public sealed class TopBuilder : ITopBuilder
    {
        private readonly ISessionConfiguration _configuration;
        private readonly ISessionFactory _sessionFactory;

        /// <summary>
        /// Initializes instance of TopBuilder.
        /// Configures internal data factories.
        /// </summary>
        /// <param name="sessionFactory">Factory for new sessions</param>
        /// <param name="configurationBuilder">Configiration builder to build configuretions for sessions</param>
        public TopBuilder(
            ISessionFactory sessionFactory,
            ISessionConfigurationBuilder configurationBuilder
            )
        {
            _sessionFactory = sessionFactory;
            //Configure internal factories
            //You can declare any number of intermidiate factories.
            //Factory can depend on other's product.
            //Ensure you have directed acyclic dependency graph.
            _configuration = configurationBuilder
                .Declare<ITop, SessionsTopFactory>()
                .Build();
        }

        /// <summary>
        ///     Creates session and injects data into it.
        ///     Gets result from session.
        ///     Code pattern can be implemented automatically.
        /// </summary>
        public ITop BuildTop(ITeamCollection teams, ITopCount count)
        {
            using (var session = _sessionFactory.Create(_configuration))
            {
                //let's inject data into our session.
                session.Set(teams);
                session.Set(count);
                //ok
                //Everything is ready.
                //Let's get result from our session.
                //SessionsTopFactory class will be used as declared by configuration.
                return session.Get<ITop>();
            }
        }
    }
}